/*
 * MIT License
 * 
 * Copyright (c) 2017 wen.gu <454727014@qq.com>
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
 

/***************************************************************************
 * Name: vos_os_win.h
 *
 * Purpose: virtual os API implement in windows system
 *
 * Developer:
 *   wen.gu , 2014-06-05
 *
 * TODO: 
 *
 ***************************************************************************/
#define _CRT_SECURE_NO_DEPRECATE


//inner header file
#include "sys_config.h"

#if defined(G_OS_WINDOWS)

//API header file
#include "vos_sys.h"

//#include "vos_log.h"

#include <windows.h>
#include <winbase.h>
#include <process.h>
#include <assert.h>


#pragma comment(lib, "winmm.lib")
/***************************************************************************
 *
 * VOS Sleep API define
 *
 ***************************************************************************/
/**
*@brief  do sleep unit in millisecond
*
*@param  ms [in] sleep time count
*
*@retuen None.
*@see 
*/
void vosSleepMs(GU32 ms)
{
    Sleep((DWORD)ms);
}

/**
*@brief  do sleep unit in second
*
*@param  sec [in] sleep time count
*
*@retuen None.
*@see 
*/
void vosSleepSec(GU32 sec)
{
    Sleep(((DWORD)sec) * 1000);
}

/***************************************************************************
 *
 * VOS System Time API define
 *
 ***************************************************************************/

/**
*@brief  get current time unit in microsecond(us)
*
*@param  None.
*
*@retuen current time unit in microsecond(us)
*@see 
*/
GS64 vosSysTimeUs(void)
{
    LARGE_INTEGER clockFreq;
    LARGE_INTEGER clockCnt;
    QueryPerformanceFrequency(&clockFreq);
    QueryPerformanceCounter(&clockCnt);

    if (clockFreq.QuadPart != 0)
    {
        return clockCnt.QuadPart * 1000000 / clockFreq.QuadPart;
    }

    return 0;
}

/**
*@brief  get current time unit in millisecond
*
*@param  None.
*
*@retuen current time unit in millisecond
*@see 
*/
GS64 vosSysTimeMs(void)
{
    return timeGetTime();
}

/**
*@brief  get current date and time
*
*@param  dt [out]  return current data and time
*
*@retuen None.
*@see 
*/
void vosSysDateTime(vosDate_t *dt)
{    
    SYSTEMTIME stTime;
    assert(dt);

    GetLocalTime(&stTime);
    dt->year = (GS32)stTime.wYear;
    dt->mon = (GS32)stTime.wMonth;
    dt->day = (GS32)stTime.wDay;
    dt->hour = (GS32)stTime.wHour;
    dt->min = (GS32)stTime.wMinute;
    dt->sec = (GS32)stTime.wSecond; 
}

/***************************************************************************
 *
 * VOS Dynamic library(or share library) API define
 *
 ***************************************************************************/
/**
*@brief  load a Dynamic library(or share library)
*
*@param  dllname [in]  dynamic library path and name
*
*@retuen if success return dl handle,else return 'NULL'.
*@see 
*/
GPHD vosLoadDLL(const GS08 *dllname)
{
    GPHD dllHd = NULL;
#ifdef UNICODE
    GSZT len = strlen((const char*)dllname);
    size_t mallocSize = (size_t)(len * (sizeof(wchar_t)) + (sizeof(wchar_t)));
    wchar_t *wdmname  = (wchar_t *)malloc(mallocSize);	

    if (!wdmname)
    {
        return NULL;
    }
    memset(wdmname, 0, mallocSize); 

    if (mbstowcs(wdmname, (const char*)dllname, (size_t)len) == -1)
    {
        free(wdmname);
        return NULL;
    }

    dllHd = LoadLibrary((LPWSTR)wdmname);
    free(wdmname);
#else
    dllHd = LoadLibrary((LPCSTR)dllname);
#endif
    return dllHd;
}

/**
*@brief  get a symbole from Dynamic library(or share library)
*
*@param  dllHd  [in]  dynamic library handle
*@param  symbol [in]  symbol name
*
*@retuen if success return symbol pointer,else return 'NULL'.
*@see 
*/
void* vosGetDLLSymbol(GPHD dllHd, const GS08 *symbol)
{
    if (dllHd && symbol)
    {
        return GetProcAddress((HMODULE)dllHd, (LPCSTR)symbol);
    }

    return NULL;
}

/**
*@brief  free a Dynamic library(or share library) handle.
*
*@param  dllHd  [in]  dynamic library handle
*
*@retuen None.
*@see 
*/
void vosFreeDLL(GPHD dllHd)
{
    if (dllHd)
    {
        FreeLibrary((HMODULE)dllHd);
    }
}

#endif //end of defined(G_OS_WINDOWS)
